package graphicinterface;

import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.LinkedList;
import javax.swing.JPanel;

/**
 * this class will show JPanels inside a giant panel and it has a page selector so
 * you can view more panels in another page
 * @author Mina
 *
 */
public class ShowsJPanelsOnManyPages extends JPanel implements KeyListener, MouseListener
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private LinkedList<JPanel> allJPanels;
	private int howManyPanelsPerPage; //how many panels should be shown in one page
	private int howManyLinesPerPage; //how many lines with JPanels one page should have.
	private MenuForPageSelection menuPageSelection;
	private JPanel giantPanelWithPanelsInside;
	
	/**
	 *everytime the current page changes, we'll need to know which JPanels from "allJPanels" should
	 *the page show. That's why we store the "indexOfFirstPanelOfPageOnAllJPanels".
	 *We use this index to know where to start getting JPanels to show on current page on
	 *the LinekdList "allJPanels".
	 */
	private int indexOfFirstPanelOfPageOnAllJPanels;
	
	public ShowsJPanelsOnManyPages(LinkedList<JPanel> allJPanels, 
							int howManyPanelsPerPage, int howManyLinesPerPage)
	{
		this.allJPanels = allJPanels;
		if(allJPanels.size() > 0)
		{
			//then there are panels to alternate through this JPanel!let's start creating this panel!
			this.putMouseListenersOnAllPanels();
			this.howManyPanelsPerPage = howManyPanelsPerPage;
			this.howManyLinesPerPage = howManyLinesPerPage;
			int howManyPanelsOnallJPanels = allJPanels.size();
			
			this.menuPageSelection =
					new MenuForPageSelection(howManyPanelsPerPage, howManyPanelsOnallJPanels);
			indexOfFirstPanelOfPageOnAllJPanels = 0;
			this.setBackground(new Color(255,131,137));
			createInicialPage();
		}
	}
	
	public void putMouseListenersOnAllPanels()
	{
		for(int i = 0; i < this.allJPanels.size(); i++)
		{
			JPanel onePanel = allJPanels.get(i);
			onePanel.addMouseListener(this);
		}
	}
	
	private void createInicialPage()
	{
		giantPanelWithPanelsInside = new JPanel();
		giantPanelWithPanelsInside.setBackground(new Color(255,131,137));
		GridBagLayout layout = new GridBagLayout();
		giantPanelWithPanelsInside.setLayout(layout);
		
		GridBagLayout layout2 = new GridBagLayout();
		this.setLayout(layout2);
		GridBagConstraints grid = new GridBagConstraints();
		grid.gridheight = this.howManyLinesPerPage;
		grid.gridy = 0;
		this.add(giantPanelWithPanelsInside, grid);
		
		grid.gridheight = 1;
		grid.gridy = this.howManyLinesPerPage + 1;
		grid.insets = new Insets(20, 0, 0, 0);
		
		menuPageSelection.setBackground(new Color(255,131,137));
		this.add(menuPageSelection, grid);
		menuPageSelection.setFocusable(true);
		menuPageSelection.addKeyListener(this);
		menuPageSelection.requestFocus();
		
		this.pageChanged(); 
		/*tecnically, the page hasnt changed, but we'll need to execute the same behavior as
		  if the page changed to fill the "giantPanelWithJPanels" with little JPanels.
		*/
	}
	
	private void pageChanged()
	{
		changeIndexOfFirstPanelOfPageOnAllJPanels();
		LinkedList<JPanel> newPanelsToShow = this.getSomePanelsToShowOnPage();
		this.changeShowingPanels(newPanelsToShow);
	}
	
	/**
	 * this function will correctly change the index based on current page
	 */
	private void changeIndexOfFirstPanelOfPageOnAllJPanels()
	{
		int currentPage = this.menuPageSelection.getCurrentPage();
		if(currentPage == 1)
		{
			this.indexOfFirstPanelOfPageOnAllJPanels = 0;
		}
		else
		{
			this.indexOfFirstPanelOfPageOnAllJPanels =
					(currentPage * howManyPanelsPerPage) - howManyPanelsPerPage; 
		}
	}
	
	/**
	 * function will retrieve from 0 to "howManyPanelsPerPage" panels of 
	 * "allJPanels" depending on where is the "indexOfFirstPanelOfPageOnAllJPanels".
	 * @return
	 */
	private LinkedList<JPanel> getSomePanelsToShowOnPage()
	{
		int howManyPanelsOnAllJPanels = allJPanels.size();
		LinkedList<JPanel> panelsToShowOnPage = new LinkedList<JPanel>();
		int howManyPanelsAreShowingInThePage = 0;
		
		int allJPanelsIterator = this.indexOfFirstPanelOfPageOnAllJPanels;
		while(howManyPanelsAreShowingInThePage < this.howManyPanelsPerPage &&
				allJPanelsIterator < howManyPanelsOnAllJPanels)
		{
			/*if the limit defined on "howManyPanelsPerPage" is reached or
			  the iterator encounter the end of the LinkedList, we've finished getting
			  JPanels to show on current page*/
			JPanel onePanel = this.allJPanels.get(allJPanelsIterator);
			panelsToShowOnPage.add(onePanel);
			howManyPanelsAreShowingInThePage = howManyPanelsAreShowingInThePage + 1;
			allJPanelsIterator = allJPanelsIterator + 1;
		}
		return panelsToShowOnPage;
	}
	
	
	/**
	 * this function will change the currently showing panels on the page
	 * @param newPanelsWithBooks can have size from 0 to "howManyPanelsPerPage"
	 */
	private void changeShowingPanels(LinkedList<JPanel> newPanels)
	{
		this.giantPanelWithPanelsInside.removeAll();
		GridBagConstraints grid = new GridBagConstraints();
		int currentColumn = 0;
		int currentLine = 0;
		for(int i = 0; i < newPanels.size(); i++)
		{
			grid.gridx = currentColumn;
			grid.gridy = currentLine;
			grid.insets = new Insets(16, 0, 0, 0);
			JPanel oneItem = newPanels.get(i);
			this.giantPanelWithPanelsInside.add(oneItem, grid);
			
			currentLine = currentLine + 1;
			if(currentLine == this.howManyLinesPerPage)
			{
				//we'll start again on another column.
				currentLine = 0;
				currentColumn = currentColumn + 1;
			}
		}
	}

	@Override
	public void keyPressed(KeyEvent e) 
	{
		int key = e.getKeyCode();
        if(key == 37 || key == 39)
        {
        	//user clicked "left arrow" or "right arrow" on keyboard
        	this.pageChanged();
        }	
	}

	@Override
	public void keyReleased(KeyEvent e) 
	{
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyTyped(KeyEvent e) 
	{
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseEntered(MouseEvent e) 
	{
		Component objectEntered = e.getComponent();
		for(int i = 0; i < this.allJPanels.size(); i++)
		{
			JPanel onePanel = this.allJPanels.get(i);
			if(objectEntered == onePanel)
			{
				onePanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));	
			}
		}
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
}
